package com.wujian.love.core.token;

import com.wujian.love.utils.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: TokenInterceptor
 * @description:
 * @author: wujian
 * @Date: 2020-06-18 15:31
 **/
@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = LoggerFactory.getLogger(FormToken.class);

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            FormToken annotation = method.getAnnotation(FormToken.class);
            if (annotation != null) {
                boolean needSaveSession = annotation.save();
                if (needSaveSession) {
                    Date d = new Date();
                    String uuid = UUID.randomUUID().toString();
                    redisUtil.set("formToken_" + uuid, "1", 3600L, TimeUnit.MINUTES);
                    request.getSession(true).setAttribute("formToken", uuid);
                    logger.warn(request.getServletPath() + "---->formToken:" + uuid);
                }
                boolean needRemoveSession = annotation.remove();

                if (needRemoveSession) {
                    if (isRepeatSubmit(request)) {
                        logger.warn("please don't repeat submit,url:" + request.getServletPath());
                        boolean pass = annotation.pass();
                        request.setAttribute("formToken_pass_repeat", "true");
                        return pass;
                    }
                    //request.getSession(true).removeAttribute("token");
                }
            }
            return true;
        } else {
            return super.preHandle(request, response, handler);
        }
    }

    private boolean isRepeatSubmit(HttpServletRequest request) {
        String clinetToken = request.getParameter("formToken");
        if (clinetToken == null) {
            return true;
        }
        boolean r = redisUtil.exists("formToken_" + clinetToken);
        if (r) {
            Long upCount = redisUtil.decr("formToken_" + clinetToken);
            //如果对更新标记做减减操作后不等0,表示是重复提交
            if (upCount != 0) {
                redisUtil.remove("formToken_" + clinetToken);
                return true;
            } else {
                redisUtil.remove("formToken_" + clinetToken);
                return false;
            }
        } else {
            return true;
        }
    }

}
